package cn.hznc.controller.service.toolAnalyze;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hznc.constant.CommonConstant;
import cn.hznc.domain.entity.MachineToolDataLog;
import cn.hznc.domain.request.common.QueryCondition;
import cn.hznc.domain.request.device.DataLogMachineToolGroupReq;
import cn.hznc.domain.request.device.MachineToolDataDetailReq;
import cn.hznc.domain.request.order.QueryOrderReq;
import cn.hznc.domain.request.order.SortCondition;
import cn.hznc.domain.response.PageResult;
import cn.hznc.mapper.MachineToolDataLogMapper;
import cn.hznc.utils.CommonUtil;
import cn.hznc.repository.MachineToolDataLogRepository;
import cn.hznc.vo.AnalysisReportOnMachineToolUsageIndexVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class MachineToolLogUsageRecordService {
    @Resource
    private MachineToolDataLogMapper machineToolDataLogMapper;

    @Resource
    private MachineToolDataLogRepository machineToolDataLogRepository;

    private static final HashMap<String, String> fieldMap = new HashMap<>();

    private static final HashMap<String, String> sortEnumMap = new HashMap<>();

    static {
        fieldMap.put("id", "id");
        fieldMap.put("warehouseId", "warehouse_id");
        fieldMap.put("warehouseName", "warehouse_name");
        fieldMap.put("length", "length");
        fieldMap.put("toolLife", "tool_life");
        fieldMap.put("toolNo", "tool_no");
        fieldMap.put("toolRadius", "tool_radius");
        fieldMap.put("toolUsageTime", "tool_usage_time");
        fieldMap.put("uniqueId", "unique_id");
        fieldMap.put("program", "program");
        fieldMap.put("time", "time");
        fieldMap.put("taskId", "task_id");
        fieldMap.put("startTime", "start_time");
        fieldMap.put("endTime", "end_time");
        fieldMap.put("seq", "seq");
        fieldMap.put("craftName", "craft_name");
        fieldMap.put("machineToolTaskId", "machine_tool_task_id");
        fieldMap.put("position", "position");
        fieldMap.put("rfid", "rfid");
        fieldMap.put("createTime", "create_time");
//        sortEnumMap.put("taskId", "TaskId");
//        sortEnumMap.put("materialNo", "MaterialNo");
//        sortEnumMap.put("heavy", "Heavy");
//        sortEnumMap.put("priority", "Priority");
//        sortEnumMap.put("productionNum", "ProductionNum");
//        sortEnumMap.put("planNumber", "PlanNumber");
//        sortEnumMap.put("realNumber", "RealNumber");
//        sortEnumMap.put("finishTime", "FinishTime");
    }

    public PageResult<MachineToolDataLog> queryMachineToolLogUsageRecord(QueryOrderReq queryProcessReq){
        PageHelper.startPage(queryProcessReq.getPageNum(),queryProcessReq.getPageSize());
        List<QueryCondition> queryConditions = new ArrayList<>();
        if (!CollectionUtil.isEmpty(queryProcessReq.getQueryConditions())) {
            queryConditions = queryProcessReq.getQueryConditions().stream().
                    filter(queryCondition -> fieldMap.getOrDefault(queryCondition.getKey(), null) != null).
                    collect(Collectors.toList());
        }
        QueryWrapper<MachineToolDataLog> wrapper = buildQueryWrapper(queryConditions);
        buildSortQueryWrapper(wrapper , queryProcessReq.getSortCondition());
        if(StringUtil.isNotEmpty(queryProcessReq.getProgram())){
            queryProcessReq.setProgram(queryProcessReq.getProgram().replaceAll("\\\\" , "\\\\\\\\"));
           wrapper.like("program" , queryProcessReq.getProgram());
        }
        List<MachineToolDataLog> machineToolDataLogList = machineToolDataLogMapper.selectList(wrapper);
//        PageInfo<MachineToolDataLog> result = new PageInfo<>(CommonUtil.pageList(machineToolDataLogList, queryProcessReq.getPageNum(), queryProcessReq.getPageSize()));
//        return new PageResult<>(result.getList(), (long)machineToolDataLogList.size());
        PageInfo<MachineToolDataLog> pageInfo = new PageInfo<>(machineToolDataLogList);
        return new PageResult<>(pageInfo.getList(), pageInfo.getTotal());


    }

    public PageResult<MachineToolDataLog> AnalysisReportOnMachineToolUsage(QueryOrderReq queryProcessReq){
        List<MachineToolDataLog> machineToolDataLogs = new ArrayList<>();
        List<QueryCondition> queryConditions = new ArrayList<>();
        if (!CollectionUtil.isEmpty(queryProcessReq.getQueryConditions())) {
            queryConditions = queryProcessReq.getQueryConditions().stream().
                    filter(queryCondition -> fieldMap.getOrDefault(queryCondition.getKey(), null) != null).
                    collect(Collectors.toList());
        }
        QueryWrapper<MachineToolDataLog> wrapper = buildQueryWrapper(queryConditions);
        buildSortQueryWrapper(wrapper , queryProcessReq.getSortCondition());
        List<MachineToolDataLog> machineToolDataLogList = machineToolDataLogMapper.selectList(wrapper);

        Map<String, Map<Integer,Map<String,List<MachineToolDataLog>>>> map = machineToolDataLogList
                .stream()
                .filter(machineToolDataLog -> ObjectUtil.isNotNull(machineToolDataLog.getMachineToolTaskId()) && StringUtils.isNotBlank(machineToolDataLog.getToolNo()) &&StringUtils.isNotBlank(machineToolDataLog.getWarehouseName()))
                .collect(Collectors.groupingBy(MachineToolDataLog::getWarehouseName,Collectors.groupingBy(MachineToolDataLog::getMachineToolTaskId,Collectors.groupingBy(MachineToolDataLog::getToolNo))));
        //Iterator<Map.Entry<String, List<MachineToolDataLog>>> entries = map.entrySet().iterator();
        map.forEach((key,value) -> {
            value.forEach((ke,va) -> {
                va.forEach((k,v) ->{
                    MachineToolDataLog machineToolDataLog = v.get(0);
                    v.forEach(machineToolDataLog1 -> {
                        if (machineToolDataLog.getToolUsageTime()<machineToolDataLog1.getToolUsageTime()) {
                            machineToolDataLog.setToolUsageTime(machineToolDataLog1.getToolUsageTime());
                        }
                    });
                    machineToolDataLogs.add(machineToolDataLog);
                });
            });
        });

//        while (entries.hasNext()){
//            Map.Entry<String, List<MachineToolDataLog>> listEntry = entries.next();
//            Double groupTime = listEntry.getValue().stream().collect(Collectors.summingDouble(MachineToolDataLog::getGroupTime));
//            MachineToolDataLog machineToolDataLog = new MachineToolDataLog();
//            machineToolDataLog.setGroupTime(groupTime);
//            machineToolDataLogs.add(machineToolDataLog);
//        }
//        PageInfo<MachineToolDataLog> result = new PageInfo<>(CommonUtil.pageList(machineToolDataLogs, queryProcessReq.getPageNum(), queryProcessReq.getPageSize()));
//        return new PageResult<>(result.getList(), (long)machineToolDataLogs.size());
        List<MachineToolDataLog> pageList = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(machineToolDataLogs)){
            pageList = CommonUtil.pageList(machineToolDataLogs , queryProcessReq.getPageNum() , queryProcessReq.getPageSize());
        }
        return new PageResult<>(pageList , (long) machineToolDataLogs.size());

    }

    public PageResult<MachineToolDataLog> AnalysisReportOnMachineToolUsageReload(QueryOrderReq queryProcessReq){
        List<MachineToolDataLog> resultList = new ArrayList<>();
        List<MachineToolDataLog> pageList = new ArrayList<>();
        if (!CollectionUtil.isEmpty(queryProcessReq.getQueryConditions())) {
            queryProcessReq.setQueryConditions(queryProcessReq.getQueryConditions().stream().
                    filter(queryCondition -> fieldMap.getOrDefault(queryCondition.getKey(), null) != null).
                    collect(Collectors.toList()));
        }
        List<MachineToolDataLog> machineToolDataLogList = machineToolDataLogRepository.selectReportOnMachineToolUsageReload(queryProcessReq);
//        QueryWrapper<MachineToolDataLog> wrapper = buildQueryWrapper(queryConditions);
//        buildSortQueryWrapper(wrapper , queryProcessReq.getSortCondition());
//        List<MachineToolDataLog> machineToolDataLogList = machineToolDataLogMapper.selectList(wrapper);

        if(!ObjectUtil.isNull(queryProcessReq.getSortCondition()) && CollectionUtil.isNotEmpty(machineToolDataLogList)){
            SortCondition sortCondition = queryProcessReq.getSortCondition();
            if(StringUtils.isNotBlank(sortCondition.getSortColumn()) && sortCondition.getSortColumn().equals("sumTime")){
                if(sortCondition.getSortType() ==0){
                    //倒序
                    machineToolDataLogList = machineToolDataLogList
                            .stream()
                            .sorted(Comparator.nullsFirst(Comparator.comparingDouble(MachineToolDataLog::getSumTime)))
                            .collect(Collectors.toList());
                }else{
                    //正序
                    machineToolDataLogList = machineToolDataLogList
                            .stream()
                            .sorted(Comparator.nullsFirst(Comparator.comparingDouble(MachineToolDataLog::getSumTime)).reversed())
                            .collect(Collectors.toList());
                }
            }
        }
        if(CollectionUtil.isNotEmpty(resultList)){
            pageList = CommonUtil.pageList(resultList , queryProcessReq.getPageNum() , queryProcessReq.getPageSize());
        }
        return new PageResult<>(pageList , (long) resultList.size());

    }

    public PageResult<AnalysisReportOnMachineToolUsageIndexVo> queryMachineToolLogUsageRecord(DataLogMachineToolGroupReq dataLogMachineToolGroupReq){
        List<AnalysisReportOnMachineToolUsageIndexVo> resultList = machineToolDataLogRepository.AnalysisReportOnMachineToolUsage(dataLogMachineToolGroupReq);
        if(ObjectUtil.isNotNull(dataLogMachineToolGroupReq.getFlag())){
            if(CollectionUtil.isNotEmpty(resultList)){
                if(dataLogMachineToolGroupReq.getFlag() ==0){
                    //正序排序
                    resultList = resultList
                            .stream()
                            .sorted(Comparator.comparing(AnalysisReportOnMachineToolUsageIndexVo::getSumTime))
                            .collect(Collectors.toList());
                }else {
                    //倒序排序
                    resultList = resultList
                            .stream()
                            .sorted(Comparator.comparing(AnalysisReportOnMachineToolUsageIndexVo::getSumTime).reversed())
                            .collect(Collectors.toList());
                }
            }
        }
        List<AnalysisReportOnMachineToolUsageIndexVo> pageList = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(resultList)){
            pageList = CommonUtil.pageList(resultList , dataLogMachineToolGroupReq.getPageNum() , dataLogMachineToolGroupReq.getPageSize());
        }
        return new PageResult<>(pageList , (long) resultList.size());

    }

    private void buildSortQueryWrapper(QueryWrapper<MachineToolDataLog> wrapper, SortCondition sortCondition) {
        if(StringUtils.isNotBlank(sortCondition.getSortColumn())){
            if(sortCondition.getSortType() == 0){
                //0是正序
                wrapper.orderByAsc(sortCondition.getSortColumn());
            }else {
                //1是倒序
                wrapper.orderByDesc(sortCondition.getSortColumn());
            }
        }
    }

    private QueryWrapper<MachineToolDataLog> buildQueryWrapper(List<QueryCondition> queryConditions) {
        QueryWrapper<MachineToolDataLog> wrapper = new QueryWrapper<>();
        for (QueryCondition queryCondition : queryConditions) {
            if (CommonConstant.EQUALS_CONDITION_CONST.equals(queryCondition.getCondition())) {
                wrapper.eq(fieldMap.get(queryCondition.getKey()), queryCondition.getValue());
            }
            if (CommonConstant.LIKE_CONDITION_CONST.equals(queryCondition.getCondition())) {
                wrapper.like(fieldMap.get(queryCondition.getKey()), queryCondition.getValue());
            }
            if (CommonConstant.BETWEEN_CONDITION_CONST.equals(queryCondition.getCondition())) {
                wrapper.between(fieldMap.get(queryCondition.getKey()), queryCondition.getStartValue(), queryCondition.getEndValue());
            }
            if (CommonConstant.NOT_EQUALS_CONDITION_CONST.equals(queryCondition.getCondition())) {
                wrapper.ne(fieldMap.get(queryCondition.getKey()), queryCondition.getValue());
            }

        }
        wrapper.ge("time" , 0.0);
        return wrapper;
    }

    public Object machineToolDataLogDetail(MachineToolDataDetailReq machineToolDataDetailReq) {
        PageHelper.startPage(machineToolDataDetailReq.getPageNum() , machineToolDataDetailReq.getPageSize());
        if(StringUtils.isNotBlank(machineToolDataDetailReq.getProgram())){
            if(machineToolDataDetailReq.getProgram().contains("\\\\")){
                machineToolDataDetailReq.setProgram(machineToolDataDetailReq.getProgram().replaceAll("\\\\" , "\\\\\\\\"));
            } else if (machineToolDataDetailReq.getProgram().contains("\\/")) {
                machineToolDataDetailReq.setProgram(machineToolDataDetailReq.getProgram().replaceAll("\\/" , "\\//"));
            }
        }
        List<MachineToolDataLog> machineToolDataLogList = machineToolDataLogRepository.machineToolDataLogDetail(machineToolDataDetailReq);
        PageInfo<MachineToolDataLog> pageInfo = new PageInfo<>(machineToolDataLogList);
        return new PageResult<>(pageInfo.getList() , pageInfo.getTotal());
    }
}
